<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2011-08-10
 * -+-----------------------------------------
 *
 * 框架常用函数类库
 * @author jinke
 */
class Functions extends Base
{
	
	
	/**
	 * 删除数组中指定值的元素
	 * @access public
	 * @param array $array 数组
	 * @param string $value 元素值
	 * @return array
	 */
	public static function arrayDeleteFromValue(Array &$array, $value)
	{
		$tep = array();
		$array = array_values($array);
		for($i=0; $i<count($array);	$i++)
		{
			if($array[$i] != $value)
			 $tep[] = $array[$i];
		}
		$array = array_values($tep);
		return $array;
	}

	
	
	
	/**
	 * 删除数组中值为空的元素
	 * @access public
	 * @param array $array 数组
	 */
	public static function arrayDeleteEmptyValue(Array &$array)
	{
		if(!empty($array))
		{
			$keys = array_keys($array);
			for($i=0; $i<count($keys); $i++)
			{
				$tep = trim($array[$keys[$i]]);
				if($tep=='')
					unset($array[$keys[$i]]);
			}
		}
		return $array;
	 }
	 
	 
	
	/**
	 * 将一个数组转换为二维数组
	 * @access public
	 * @param array $array 数组
	 * @return array
	 */
	public static function arrayOneDimToTwo(Array &$array)
	{
		$tep = array();
		if (is_array($array))
		{
			if (isset($array[0])  && is_array($array[0]))
				$array = $array;
			else
				$tep[] = $array;
		}
		else
			$array = $tep;
		return $array;
	}
	
	
	
	
	/**
	 * 日期格式转换为数组 2010-03-08 12:01:57
	 * @access public
	 * @param string $date
	 * @return array
	 */
	public static function dateStringToArray($date)
	{
		if(strpos($date,' ',0)>0)
		{
			$bak = split(' ',$date);
			$tep = split('-',$bak[0]);
			$tep2 = split(':',$bak[1]);
			$tep = array_merge($tep,$tep2);
		}
		else
			return false;
		return $tep;
	}
	
	
	
	/**
	 * 给字符串结尾添加 / ，确保以 /结尾
	 * @access public
	 * @param string $string 字符串
	 * @return string
	 */
	public static function stringEndAddSlash($string)
	{
		if($string=='') return $string;
		
		$string=str_replace('//','/',$string);
		if(@strpos($string,'/',strlen($string)-1))
			return $string;
		else
			return $string.'/';
	}
	
	
	
	/**
	 * 获取应用程序下的各种配置文件资料
	 * @access public
	 * @param string $string 例：admin.common.default_dbkey
	 * @return array
	 */
	public static function getAppConfig($string)
	{
		$exp = explode('.',	 $string);
		$appName = isset($exp[0]) ? $exp[0] : APP_NAME;
		$fileName = isset($exp[1]) ? $exp[1] : '';
		$item = isset($exp[2]) ? $exp[2] : '';
		
		$file = BASE_DIR.Config::get('app_folder').'/'.$appName.'/config/'.$fileName.'.inc.php';
		if (is_file($file))
		{
			if($item=='')
				return require $file;
			else
			{
				$array = require $file;
				if( isset($array[$item]))
					return $array[$item];
				else
					return false;
			}
		}
		return false;
	}
	
	
	
	/**
	 * 通用发邮箱函数
	 * @access public
	 * @param string $title    标题，默认为GB2312编码
	 * @param string $html     Html信体,默认为GB2312编码
	 * @param string $text     纯文本信体,默认为GB2312编码
	 * @param string $email    收件人地址
	 * @param string $user     收件从称谓
	 * @param array  $config   邮件发送参数[可选]
	 * @return boolean         返回邮件发送情况
	 */
	public static function sendMail($title,$html,$text,$email,$user=null,$config=array())
	{
	
		require_once(FRAMEWORK_LIB_DIR."phpmailer/class.phpmailer.php");
		if(empty($config))
			$config = Config::get('mail');
		//下面是几个不常用到的变量
		$charset=empty($config["charset"])?'UTF-8':$config["charset"];
		$encode=empty($config["encoding"])?'base64':$config["encoding"];
		$debug=empty($config["debug"])?false:$config["debug"];
	
		//初始化邮件类
		$mail = new PHPMailer();
		$mail->IsSMTP();                           // send via SMTP
		$mail->Host        = $config["host"];      // SMTP servers
		$mail->SMTPAuth    = true;                 // turn on SMTP authentication 开启验证
		$mail->Username    = $config["user"];      // SMTP username  注意：普通邮件认证不需要加 @域名
		$mail->Password    = $config["pass"];      // SMTP password
		$mail->From        = $config["user"];      // 发件人邮箱
		$mail->FromName    = $config["name"];      // 发件人
		$mail->CharSet     = $charset;             // 这里指定字符集！
		$mail->Encoding    = $encode;              // 编码方式
		$mail->SMTPDebug   = $debug;               // 调试用的开关
		$mail->AddReplyTo($config["user"],$config["name"]);
	
		if (!empty($config["gmail"]))
		{
			$mail->SMTPSecure = empty($config["Secure"])?'ssl':$config["Secure"];
			$mail->Port = empty($config["port"])?465:$config["port"];
		}
		$mail->Subject = $title;
		if(!empty($config["istext"]))
		{
			$mail->IsHTML(false);			
			$mail->Body = $text;
		}
		else
		{
			$mail->IsHTML(true);
			$mail->AltBody = $text;  //不支持html格式时，显示的文本
			$mail->Body = $html;//html信体
		}
		$mail->AddAddress($email,$user);
		return $mail->Send();
	}
	
	
	/**
	 * 获取当前日期
	 * @access public
	 * @param int $time 时间数值[可选]
	 */
	public static function date($time = '')
	{
		if($time=='')
			return date('Y-m-d');
		else
		{
			if($time==0)
				return '';
			else
				return date('Y-m-d',$time);
		}
	}
	
	
	/**
	 * 获取当前时间
	 * @access public
	 * @param int $time 时间数值[可选]
	 */
	public static function time($time = '')
	{
		if($time=='')
			return date('Y-m-d H:i:s');
		else
		{
			if($time==0)
				return '';
			else
				return date('Y-m-d H:i:s', $time);
		}
	}
	
	


	/**
	 * 内容过滤器 过滤数组中的值
	 * @access public
	 * @param string $text 内容
	 * @param array $arr 将要过滤的内容 一维数组
	 * @return string
	 */
	 public static function contentFilterByArray(&$text, Array $array=array())
	 {
		if($text == '')	return $text;
		if(empty($array)) return $text;
		else
		 {
			for($i=0;$i<count($array);$i++)
			{
				$text = str_replace($array[$i],'',$text);
			}
			return $text;
		 }
	 }
	 
	 
	 /**
	  * 获取当前请求页面的URL
	  * @access public
	  * @return string
	  */
	public static function getLocation()
	{
		return "http://".$_SERVER ['HTTP_HOST'].$_SERVER['PHP_SELF'];
	}
	
	
	/**
	 * 获取当前精确的时间
	 * @access public
	 * @return float
	 */
	public static function getMicroTime()
	{
	    list($usec, $sec) = explode(' ',microtime());
	     return ((float)$usec + (float)$sec);
	}
	
	
	/**
	 * URL 跳转
	 * @access public
	 * @param string $url 跳转的URL
	 */
	public static function go($url)
	{
		//检测是否存在对应的扩展
		if(function_exists('go'))
		{
			go($url);
			return;
		}
		if(substr($url,0,7)=='http://')
			header("location:".$url);
		else
			header("location:".URL.$url);
		exit;
	}
	
	
	/**
	 * 弹出 JS Alert 信息框[可扩展]
	 * @access public
	 * @param String $msg 显示的消息
	 * @param String $url 跳转的URL
	 */
	public static function alert($msg,$url='')
	{
		//检测是否存在对应的扩展
		if(function_exists('alert'))
		{
			alert($msg, $url);
			return;
		}
		if(empty($url))
		{
			echo'<script>alert("'.$msg.'");history.go(-1);</script>';
		}
		else
			echo'<script>alert("'.$msg.'");location.href=\''.$url.'\'</script>';
		exit;
	 }
	
	
	/**
	 * 返回上一页
	 * @access public
	 */
	public static function back()
	{	
		//检测是否存在对应的扩展
		if(function_exists('back'))
		{
			back();
			return;
		}
		echo'<script>self.location=document.referrer;</script>';
	}
		
	
	/**
	 * 实例化一个系统类或自定义类
	 * @access private
	 * @param string $classname 类名称
	 */
	public static function LIB($classname)
	{
		if(empty($classname))
			return false;
		else
		{
			//优先检查对象池中是否已对在该对象
			if(self::REG($classname))
				return self::REG($classname);
			else
			{
				//优先检查系统类库
				if(is_file(FRAMEWORK_LIB_DIR.$classname.'.class.php'))
				{
					//如果已找到类
					if($_class=_Class($classname))
					{ 
						self::RES($classname,$_class);
						return $_class;
					}
					else
						return false;
				}
				elseif(is_file(EXTEND_LIB_DIR.$classname.'.php'))
				{
					if($_class=_Class($classname,false,'extend'))
					{
						self::RES($classname,$_class);
						return $_class;
					}
					else
						return false;
				}
				else
					return false;
			}
		}
	}
	
	
	/**
	 * 引入一个或多个辅助函数库
	 * @access private
	 * @param string|array $name 字符串或数组
	 * @param bool $flag 布尔值 TRUE 系统目录
	 * @param bool $error 是否打印出错信息
	 */
	public static function FUN($name,$flag=true,$error=true)
	{
	
		if($flag)
			$dir = FRAMEWORK_FUN_DIR;
		else
			$dir = EXTEND_FUN_DIR;
	
		if (is_array($name))
		{
			for($i = 0; $i < count($name); $i++)
			{
				$file = $dir.$name[$i].'.php';
				if (file_exists(strtolower($file)))
					require_once $file;
			}
		}
		elseif (is_file(strtolower($dir.$name.'.php')))
			require_once $dir.$name.'.php';
		elseif ($error)
			message_error('Load File','无法加载函数库文件！',message_debug(debug_backtrace()));
	}
	
	/**
	 * 获取当前控制器所对应的一个表单验证规则数组
	 * @access public
	 * @param string 规则名称
	 */
	public static function vali($name)
	{
		//规则所在位置
		$file = APP_DIR.'/config/'.APP_C.'.vali.php';
		if(is_file($file))
		{
			require $file;
			if(isset($array[$name]))
				return $array[$name];
			else
				return false;
		}
		else
			message_error('Load File','无法加载表单验证规则文件！',message_debug(debug_backtrace()));
		 
	 }
	 
	 
	 
///////////////////////////////////////////////////////////// 注册函数 /////////////////////////////////////////////////////////
	/**
	 * 快速获取已注册的对象
	 * @access public
	 * @param string $key 注册的KEY名称
	 */
	public static function REG($key)
	{		
		if(Registry::get($key))
			return Registry::get($key);
		else
			return false;	
	}
	
	
	
	/**
	 * 快速注册对象
	 * @access public
	 * @param string $key 注册的KEY名称
	 * @param object $objName  要注册的对象名称
	 * @param array $args  调用对象的构造函数时需要的参数列表
	 * @param bool $sys 是否为系统对象
	 */
	public static function REC($key,$objName = '',$args = array(),$sys = true,$reset_obj=false)
	{
		if($reset_obj===true)
			Registry::$reset_obj =true;
		else
			Registry::$reset_obj =false;
		 return Registry::create($key,$objName,$args,$sys);
	}
	
	
	
	
	/**
	 * 快速注册对象 如果存在则覆盖
	 * @access public
	 * @param string $key	注册的KEY名称
	 * @param object $$data	 要注册的对象名称
	 */
	public static function RES($key,$data)
	{
		return Registry::set($key,$data);
	}
	
	/**
	 * 快速注册对象 总是不覆盖
	 * @access public
	 * @param string $key	注册的KEY名称
	 * @param object $$data	 要注册的对象名称
	 */
	public static function REA($key,$data)
	{
		 return Registry::add($key,$data);
	}
	
	/**
	 * 快速注册对象  以一维数组中的方式添加到一个列表中
	 * @access public
	 * @param string $key	注册的KEY名称
	 * @param object $$data	 要注册的对象名称
	 */
	public static function REAS($key,$data)
	{
		 return Registry::adds($key,$data);
	}
	

	
	
	 /**
	  *	 快速实例化 model
	  *	 @param string $className	例：user.user
	  */
	public static function M($className,$modelDriveType = MODEL_DB_TYPE_MYSQL)
	{
		$tep = explode('.', str_replace(' ', '', $className));
		if (count($tep)==1)
			message_error('Load Model',"M('".$className."')<br/>无法加载Model,缺少应用程序名称！",message_debug(debug_backtrace()));
	
		//获取应用程序名称及model名称
		$appName = $tep[0];
		$modName = $tep[1];
		if (self::REG('M_MODEL_INIT_LIST_'.strtolower($className)))
			return self::REG('M_MODEL_INIT_LIST_'.strtolower($className));
		self::REAS('M_FUN_LIST_TEXT', "M('".$className."')");
		//注册正在调用的MODEL所在的APP名称
		if(self::REG('M_FUN_APP_NAME'))
		{
			$_app = self::REG('M_FUN_APP_NAME');
			self::RES('M_FUN_APP_NAME', $_app.','.$appName);
		}
		else 
			self::RES('M_FUN_APP_NAME', $appName);
		
		//导入类文件
		$file = BASE_DIR.Config::get('app_folder').'/'.$appName.'/models/'.ucfirst($modName).'Model.class.php';
	
		$class = null;
		//如果不存在该model类文件，则动态创建model对象
		if (!is_file($file))
		{
			if ($modelDriveType == MODEL_DB_TYPE_MYSQL)
				$class = new MysqlModel($modName,$appName);
			else if ($modelDriveType == MODEL_DB_TYPE_MONGODB)
				$class = new MongoModel($modName,$appName);
		}
		else
		{ 
			
			$class = ucfirst($modName).'Model';
			
			//如果多个应用程序里的model名称冲突，则动态创建一个新的model类文件
			if(class_exists($class)){
				
				$class = ucfirst($appName).ucfirst($modName).'Model';
				$var = Files::read($file);
				preg_match('/class(\s)+(.*)?(\s)+extends/isU',$var,$t);
				$var = str_replace($t[2],ucfirst($appName).$t[2],$var);
				$file = strtolower(TEMP_DIR.'cache/modelfile/');
				Files::mkdirs($file);
				Files::write($file.$class.'.class.php', $var);
				require_once $file.$class.'.class.php';
				$class=new $class();
			}else{
				require_once $file;
				$class=new $class();
			}
			
		}
		self::RES('M_MODEL_INIT_LIST_'.strtolower($className),$class);
		$mf = self::REG('M_MODEL_INIT_LIST_FILE');
		$mf[ucfirst($modName).'Model'] = $file;
		self::RES('M_MODEL_INIT_LIST_FILE',$mf);
		return $class;
	}
	
	
	/**
	 * M函数加强版  MX('数据库配置key.[表名|model]');  MX('app名称.[表名|model]'); 
	 * @param string $className
	 */
	public static function MX($className)
	{
		$tep = explode('.', str_replace(' ', '', $className));
		if (count($tep)==1)
			message_error('Load Model',"M('".$className."')<br/>无法加载Model,缺少应用程序名称！",message_debug(debug_backtrace()));
		//获取应用程序名称及model名称
		$appName = $tep[0];
		$modName = $tep[1];
		//导入类文件
		$file = BASE_DIR.Config::get('app_folder').'/'.$appName.'/models/'.ucfirst($modName).'Model.class.php';
	
		$class = null;
		//如果不存在该model类文件，则动态创建model对象
		if (!is_file($file) && !is_dir(strtolower(BASE_DIR.$appName))){
			$class = new Mysql_Model($modName);
			$class->_dbName =  DBTool::getDBName($appName);
			$class->getConnect();
			return $class;
		}else 
			return M($className);
	}
	
	
	
	/**
	 * 快速调用Widget
	 * @param string $name Widget名称
	 * @param array	$data 数据
	 */
	public static function W($name,Array $data = array())
	{
		if(empty($name))
			return;
	
		$widget_file = APP_DIR.'/widget/'.ucfirst($name).'Widget.class.php';
	
		if(!is_file($widget_file))
			$widget_file = SYSTEM_DIR.'widget/'.ucfirst($name).'Widget.class.php';
	
		if(is_file($widget_file))
		{
			require_once FRAMEWORK_LIB_DIR.'widget.class.php';
			require_once $widget_file;
			$class_name	= ucfirst($name).'Widget';
			$widget	= new $class_name;
			return $widget->render($data);
		}
		else
			return;
	
	}
	
	
	/**
	 * 获取参数值
	 * @access public
	 * @param string $key 参数名
	 * @param string $null 不存时返回的内容
	 * @param bool $strtolower 是否转换为小写
	 */
	public static function GET($key='', $null=false, $strtolower=false)
	{
		//获取URI参数
		$_args=self::REG('FW_Router')->getArgs();
		$_args = array_merge($_args,$_GET);
		//如果参数名为空，则返回所有参数
		if(empty($key))
			return $_args;
		//参数名不为空时，检查参数是否存在URI
		elseif(isset($_args[$key]))
		{
			if($strtolower)
				return  urldecode(strtolower($_args[$key]));
			else
				return  urldecode($_args[$key]);
		}
		else
			return $null;
	}

}
?>
